package org.nch.videoLauncher.view;

import org.nch.videoLauncher.presenter.AddEditVideoPresenter;
import org.nch.videoLauncher.domain.VideoItem;

import javax.swing.*;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.table.AbstractTableModel;
import java.util.List;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.awt.*;
import java.io.File;

/**
 * Created by IntelliJ IDEA.
 * User: bill
 * Date: Nov 18, 2008
 * Time: 4:00:46 PM
 * To change this template use File | Settings | File Templates.
 */
public class AddEditVideoView implements IContentPanel, IAddEditVideoView{
    private JPanel mainPanel;
    private JPanel gridPanel;
    private JPanel formPanel;
    private JTable videoItemTable;
    private JButton addButton;
    private JButton deleteButton;
    private JTextField titleText;
    private JTextField filenameText;
    private JPanel gridButtonPanel;
    private JScrollPane tableScrollPane;
    private JButton browseButton;
    private JButton playNowButton;
    private JTextField urlText;
    private JButton openURLButton;
    private JLabel titleLabel;
    private JLabel filenameLabel;
    private JLabel urlLabel;
    private JTextField keywordsText;
    private JTextArea descriptionText;
    private JTextField runtimeText;
    private JLabel runtimeLabel;
    private JTabbedPane tabPane;
    private JPanel generaltabPanel;
    private JPanel imdbtabPane;
    private JPanel descriptiontabPane;
    private JLabel descriptionLabel;
    private JLabel keywordsLabel;
    private JTextField keyText;
    private JPanel sporttabPanel;
    private JPanel tvtabPane;
    private JTextField sportText;
    private JTextField seasonText;
    private JTextField teamText;
    private JTextField directedText;
    private JTextField writtenText;
    private JTextField imdbTitleText;
    private JTextField ratingText;
    private JTextField mpaaText;
    private JTextField dateText;
    private JTextField castText;
    private JButton generalSaveButton;
    private JButton descriptionSaveButton;
    private JButton imdbSaveButton;
    private JButton sportsSaveButton;
    private JLabel keyLabel;
    private JLabel imdbTitleLabel;
    private JLabel ratingLabel;
    private JLabel dateLabel;
    private JLabel directedLabel;
    private JLabel writtenLabel;
    private JLabel mpaaLabel;
    private JLabel castLabel;
    private JLabel sportLabel;
    private JLabel seasonLabel;
    private JLabel teamLabel;
    private JTextField showText;
    private JTextField tvseasonText;
    private JButton tvSaveButton;
    private JLabel showLabel;
    private JLabel tvseasonLabel;
    private JLabel episodeLabel;
    private JButton fetchButton;
    private JLabel coverimageLabel;
    private JPanel fillerPanel;
    private JButton exitButton;

    private AddEditVideoPresenter presenter;
    private List<VideoItem> videoList;
    private Integer currentTableRow;
    private Image coverImage;
    private ImageIcon coverImageIcon;

    private tableModel videoItemTableModel;
    private String selectedFilename;


    private JTextField episodeText;
    private JPanel filestabPane;
    private JList fileList;
    private JTextField selectedFileText;
    private JButton browseFileButton;
    private JButton fileSaveButton;
    private JPanel fileButtonPanel;
    private JButton addFileButton;
    private JButton removeFileButton;
    private JLabel fileListLabel;
    private JScrollPane fileListScrollPane;
    private JTextField competitionText;
    private JTextField sportDateText;
    private JLabel competitionLabel;
    private JLabel sportDateLabel;
    private JButton tvCopyButton;

    private DefaultListModel fileListModel;
    private Integer currentFileListRow;

    public AddEditVideoView() {

        currentTableRow = null;
        currentFileListRow = -1;

        titleText.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (validateForm()){
                    presenter.detailsChanged();
                    videoItemTableModel.fireTableDataChanged();
                }
            }
        });
        filenameText.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (validateForm()){
                    presenter.detailsChanged();
                    videoItemTableModel.fireTableDataChanged();
                }
            }
        });
        urlText.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (validateForm()){
                    presenter.detailsChanged();
                    videoItemTableModel.fireTableDataChanged();
                }
            }
        });        
        addButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                presenter.addNewItem();
                videoItemTableModel.fireTableDataChanged();
                setCurrentSelection(0);
                titleText.requestFocus();

            }
        });
        deleteButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                presenter.deleteItem(getCurrentSelection());
                setCurrentSelection(0);
                videoItemTableModel.fireTableDataChanged();
                
            }
        });
        browseButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                presenter.browseFileButtonPressed();
                videoItemTableModel.fireTableDataChanged();
                setCurrentSelection(currentTableRow);
                filenameText.requestFocus();
            }
        });
        playNowButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                presenter.playItem(currentTableRow);
                
            }
        });
        openURLButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (urlText.getText() != null){
                    presenter.openUrl(currentTableRow);
                }

            }
        });
        keywordsText.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (validateForm()){
                    presenter.detailsChanged();
                    videoItemTableModel.fireTableDataChanged();
                }
            }
        });
        runtimeText.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (validateForm()){
                    presenter.detailsChanged();
                    videoItemTableModel.fireTableDataChanged();
                }
            }            
        });
        keyText.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                presenter.imdbFetchRequested();
                videoItemTableModel.fireTableDataChanged();
            }
        });
        fetchButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                presenter.imdbFetchRequested();
                videoItemTableModel.fireTableDataChanged();
            }
        });
        imdbSaveButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (validateForm()){
                    presenter.detailsChanged();
                    videoItemTableModel.fireTableDataChanged();
                }
            }
        });
        generalSaveButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (validateForm()){
                    presenter.detailsChanged();
                    videoItemTableModel.fireTableDataChanged();
                }
            }
        });
        descriptionSaveButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (validateForm()){
                    presenter.detailsChanged();
                    videoItemTableModel.fireTableDataChanged();
                }
            }
        });
        sportsSaveButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (validateForm()){
                    presenter.detailsChanged();
                    videoItemTableModel.fireTableDataChanged();
                }
            }
        });
        tvSaveButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (validateForm()){
                    presenter.detailsChanged();
                    videoItemTableModel.fireTableDataChanged();
                }
            }
        });
        addFileButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                presenter.addFileButtonPressed();
            }
        });
        removeFileButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                presenter.deleteFileButtonPressed();
            }
        });
        browseFileButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                presenter.browseFileListButtonPressed();
            }
        });
        fileList.addListSelectionListener(new ListSelectionListener() {
            public void valueChanged(ListSelectionEvent event) {
                if (event.getValueIsAdjusting())
                        return;

                if (fileListModel.size() == 0)
                        return;

                if (!fileList.isSelectionEmpty()) {

                        currentFileListRow = fileList.getSelectedIndex();
                        presenter.fileSelectionChanged(currentFileListRow);
                 } else {
                    if (fileListModel.size() > currentFileListRow){
                        setCurrentFileSelection(currentFileListRow);
                    }
               }
            }
        });
        fileSaveButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                if (validateForm()){
                    presenter.detailsChanged();
                    videoItemTableModel.fireTableDataChanged();
                }
            }
        });
        tvCopyButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent event) {
                presenter.copyTvShowPressed();
                videoItemTableModel.fireTableDataChanged();
                setCurrentSelection(0);                
            }
        });
    }

    public JPanel getRootComponent() {
        return this.mainPanel;
    }

    // getters and setters for data entry fields

    public void setDetailTitle(String title) {
        titleText.setText(title);
    }

    public void setDetailFilename(String filename) {
        filenameText.setText(filename);
    }

    public void setDetailUrl(String url) {
        urlText.setText(url);
    }

    public void setDetailDescription(String description) {
        descriptionText.setText(description);
    }

    public void setDetailKeywords(String keywords) {
        keywordsText.setText(keywords);
    }

    public void setRuntime(String runtime) {
        runtimeText.setText(runtime);
    }

    public void setImdbKey(String key) {
        keyText.setText(key);
    }

    public void setImdbTitle(String title) {
        imdbTitleText.setText(title);
    }

    public void setImdbRating(String rating) {
        ratingText.setText(rating);
    }

    public void setImdbDate(String date) {
        dateText.setText(date);
    }

    public void setImdbDirected(String directed) {
        directedText.setText(directed);
    }

    public void setImdbWritten(String written) {
        writtenText.setText(written);
    }

    public void setImdbMpaa(String mpaa) {
        mpaaText.setText(mpaa);
    }

    public void setImdbCast(String cast) {
        castText.setText(cast);
    }

    public void setSportSport(String sport) {
        sportText.setText(sport);
    }

    public void setSportSeason(String season) {
        seasonText.setText(season);
    }

    public void setSportTeam(String team) {
        teamText.setText(team);
    }

    public void setSportDate(String date){
        sportDateText.setText(date);
    }

    public void setSportCompetition(String competition){
        competitionText.setText(competition);
    }

    public void setTvShow(String show) {
        showText.setText(show);
    }

    public void setTvSeason(String season) {
        tvseasonText.setText(season);
    }

    public void setTvEpisode(String episode) {
        episodeText.setText(episode);
    }

    public void setCoverImage(byte[] img) {
        coverImage = Toolkit.getDefaultToolkit().createImage(img);
        coverImageIcon = new ImageIcon(coverImage);
        coverimageLabel.setIcon(coverImageIcon);
    }

    public void clearImage() {
        coverImageIcon = new ImageIcon();
        coverimageLabel.setIcon(coverImageIcon);
    }

    public String getDetailTitle() {
        return titleText.getText();
    }

    public String getDetailFilename() {
        return filenameText.getText();
    }

    public String getDetailUrl() {
        return urlText.getText();
    }

    public String getSelectedFilename() {
        return selectedFilename;
    }

    public String getDescription() {
        return descriptionText.getText();
    }

    public String getKeywords() {
        return keywordsText.getText();
    }

    public String getRuntime() {
        return runtimeText.getText();
    }

    public String getImdbKey() {
        return keyText.getText();
    }

    public String getImdbTitle() {
        return imdbTitleText.getText();
    }

    public String getImdbRating() {
        return ratingText.getText();
    }

    public String getImdbDate() {
        return dateText.getText();
    }

    public String getImdbDirected() {
        return directedText.getText();
    }

    public String getImdbWritten() {
        return writtenText.getText();
    }

    public String getImdbMpaa() {
        return mpaaText.getText();
    }

    public String getImdbCast() {
        return castText.getText();
    }

    public String getSportSport() {
        return sportText.getText();
    }

    public String getSportSeason() {
        return seasonText.getText();
    }

    public String getSportTeam() {
        return teamText.getText();
    }

    public String getSportDate(){
        return sportDateText.getText();
    }

    public String getSportCompetition(){
        return competitionText.getText();
    }

    public String getTvShow() {
        return showText.getText();
    }

    public String getTvSeason() {
        return tvseasonText.getText();
    }

    public String getTvEpisode() {
        return episodeText.getText(); 
    }

    // method to check if the details of the video item have been edited

    public boolean getDetailHasChanged() {

        System.out.println("Checking for changes in row: " + currentTableRow);

        if (currentTableRow == null || currentTableRow == -1)
            return false;

        VideoItem currentVideoItem = videoList.get(currentTableRow);

        if (titleText.getText().equals("") && filenameText.getText().equals(""))
            return false;

        if (!titleText.getText().equals(currentVideoItem.getTitle()))
            return true;   // title has changed

        if (!filenameText.getText().equals(currentVideoItem.getFilename()))
            return true;   // filename has changed        

        if ((urlText.getText() != "") && (!(urlText.getText().equals(currentVideoItem.getUrl()))))
            return true;

        return false;

    }

    // return the index of the current table selection

    public Integer getCurrentSelection() {
        return this.currentTableRow;
    }

    // set the current grid selection

    public void setCurrentSelection(Integer index) {
        videoItemTable.getSelectionModel().setSelectionInterval(index, index);
    }

    // blank out all the form details

    public void clearDetails() {

        titleText.setText("");
        filenameText.setText("");
        urlText.setText("");
        runtimeText.setText("");
        descriptionText.setText("");
        keywordsText.setText("");
        keyText.setText("");
        imdbTitleText.setText("");
        ratingText.setText("");
        dateText.setText("");
        directedText.setText("");
        writtenText.setText("");
        mpaaText.setText("");
        castText.setText("");
        sportText.setText("");
        seasonText.setText("");
        teamText.setText("");
        showText.setText("");
        tvseasonText.setText("");
        episodeText.setText("");
        sportDateText.setText("");
        competitionText.setText("");

        clearImage();
        fileListModel = new DefaultListModel();
        fileList.setModel(fileListModel);
        currentFileListRow = -1;
    }

    // iterate through all the form controls and and enable/disable them

    public void setDetailsEnabled(boolean enabled) {

        Component[] tablist = tabPane.getComponents();
        for (Component container: tablist){
            JPanel tab = (JPanel) container;
            Component[] controls = tab.getComponents();
            for (Component c: controls){
                c.setEnabled(enabled);
            }
        }
        setAddFileButtonEnabled(false);
        setDeleteFileButtonEnabled(false);
        setBrowseFileButtonEnabled(false);
    }

    // enable the open URL button

    public void setBrowseUrlEnabled(boolean enabled) {
        openURLButton.setEnabled(enabled);
    }

    // enable the play now button

    public void setPlayNowEnabled(boolean enabled) {
        playNowButton.setEnabled(enabled);
    }

    // enable the fetch button

    public void setFetchEnabled(boolean enabled) {
        fetchButton.setEnabled(enabled);
    }

    // show file dialog and return success/fail

    public boolean isFileSelected(String baseVideoPath) {
        File file = new File(baseVideoPath);
        JFileChooser jfc = new JFileChooser(file);
        jfc.setDialogType(JFileChooser.OPEN_DIALOG);
        jfc.setFileSelectionMode(JFileChooser.FILES_ONLY);
        jfc.setMultiSelectionEnabled(false);
        Integer returnValue = jfc.showOpenDialog(null);
        if (returnValue == JFileChooser.APPROVE_OPTION){
            file=jfc.getSelectedFile();
            this.selectedFilename = file.getAbsolutePath().substring(baseVideoPath.length()+1, file.getAbsolutePath().length());
            //videoItemTableModel.fireTableDataChanged();
            return true;
        } else {
            filenameText.requestFocus();
            return false;
        }

    }

    // model for the table, using the video item collection


    private class tableModel extends AbstractTableModel{

            public int getRowCount(){ return videoList.size();}
            public int getColumnCount(){ return 3;}

            public String getColumnName(int col){    // TODO:  need a cleaner implementation of the table column names
                String headings[] = new String[]{"Title", "Filename", "URL"};
                return headings[col];
            }

            public Object getValueAt(int row, int col) {
                if (col == 0)
                    return videoList.get(row).getTitle();
                if (col == 1)
                    return videoList.get(row).getFilename();
                else{
                    return videoList.get(row).getUrl();
                }
            }
    };

    // event handler for the table

    private class SelectionListener implements ListSelectionListener {

        JTable table;

        SelectionListener(JTable table){
            this.table = table;
        }

        public void valueChanged(ListSelectionEvent event) {

              // TODO:  prompt user if there are unsaved changes in the details form

//            if ((!event.getValueIsAdjusting()) && getDetailHasChanged()){
//                if (JOptionPane.showConfirmDialog(null,
//                        "You have made changes to the current item, do you want to keep them?",
//                        "Keep changes?",
//                        JOptionPane.YES_NO_OPTION,
//                        JOptionPane.QUESTION_MESSAGE) == JOptionPane.YES_OPTION){
//
//                    // push changes into the model
//
//                    System.out.println("Row " + currentTableRow + " has changes.");
//                    presenter.detailsChanged();
//
//                }
//
//                // change the selection
//
//                presenter.selectionChanged(table.getSelectedRow());
//                currentTableRow = table.getSelectedRow();
//                System.out.println("current table row: " + currentTableRow);
//                return;
//
//
//            } else

            if (!event.getValueIsAdjusting()){

                if (table.getSelectedRow() != -1){
                    presenter.selectionChanged(table.getSelectedRow());
                    currentTableRow = table.getSelectedRow();
//                    System.out.println("current table row: " + currentTableRow);
                }
                else{
                    // set the selection to the current selection
                    setCurrentSelection(currentTableRow);
//                    System.out.println("current table row: " + currentTableRow);
                } 
            }

        }
    }

    // load up the video list in the table

    public void setVideoList(List<VideoItem> videoItems) {
        this.videoList = videoItems;
        videoItemTableModel = new tableModel();
        videoItemTable.setModel(videoItemTableModel);
        videoItemTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        videoItemTable.getSelectionModel().addListSelectionListener(new SelectionListener(videoItemTable));
    }

    // assign the presenter for this view

    public void setPresenter(AddEditVideoPresenter addEditVideoPresenter){
        this.presenter = addEditVideoPresenter;
    }

    // front end validation, must return true to allow invoke presenter to handle detail changes

    private boolean validateForm(){
        if (titleText.getText().equals(""))
        {
            titleText.setBackground(Color.PINK);
            titleText.setToolTipText("Video title cannot be blank");
            return false;
        }
        else
        {
            titleText.setBackground(Color.WHITE);
            titleText.setToolTipText("");
            return true;
        }
    }

    public Integer getCurrentFileSelection() {
        currentFileListRow = fileList.getSelectedIndex();
        return currentFileListRow;
    }

    public void setCurrentFileSelection(Integer index) {
        fileList.getSelectionModel().setSelectionInterval(index, index);
        currentFileListRow = index;
    }

    public void addFileListElement(String name) {
        fileListModel.add(currentFileListRow + 1, name);
        currentFileListRow = fileListModel.size() - 1;
//        setCurrentFileSelection(currentFileListRow);
    }

    public void removeFileListElement(Integer index) {
        fileListModel.remove((int)index);
    }

    public void updateFileListElement(Integer index, String name) {
        fileListModel.setElementAt(name, index);
    }

    public void setAddFileButtonEnabled(boolean enabled) {
        addFileButton.setEnabled(enabled);
    }

    public void setDeleteFileButtonEnabled(boolean enabled) {
        removeFileButton.setEnabled(enabled);
    }

    public void setBrowseFileButtonEnabled(boolean enabled) {
        browseFileButton.setEnabled(enabled);
    }

    public String getBrowseFileText() {
        return selectedFileText.getText();
    }

    public void setBrowseFileText(String filename){
        selectedFileText.setText(filename);
    }

    public void setTvCopyButtonEnabled(boolean enabled) {
        tvCopyButton.setEnabled(enabled);
    }
}


